/**
 * 
 */
package edu.gtcfla.km.appmodules.service.impl;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.vsg.biz.BusinessEntityFactory;
import org.vsg.biz.BusinessOperationException;
import org.vsg.common.model.algstrategy.GenTreeModelBuilder;
import org.vsg.common.model.json.TreeNode;
import org.vsg.common.page.PaginationManager;

import edu.gtcfla.km.Category;
import edu.gtcfla.km.UserGroup;
import edu.gtcfla.km.UserGroupPermission;
import edu.gtcfla.km.UserPermission;
import edu.gtcfla.km.appmodules.service.UserGroupPermissionService;
import edu.gtcfla.km.appmodules.vo.CurrentUserCategoryPermissionVO;
import edu.gtcfla.km.appmodules.vo.UserGroupPermissionListVO;
import edu.gtcfla.km.repositories.UserGroupPermissionRepo;
import edu.gtcfla.km.repositories.UserGroupRepo;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author vison
 *
 */
public class UserGroupPermissionServiceI implements UserGroupPermissionService {

	@Autowired(required=false)
	private edu.gtcfla.km.repositories.CategoryRepo<Category,String> categoryRepo;

	@Autowired(required=false)	
	private UserGroupPermissionRepo<UserGroupPermission,String> userGroupPermissionRepo;
	
	@Autowired(required=false)	
	private UserGroupRepo<UserGroup, String> userGroupRepo;
	
	@Autowired(required = false)
	private SubjectManager subjectManager;	
	
	@Autowired(required=false)
	private PaginationManager paginationManager;	

	@Autowired(required=false)
	private BusinessEntityFactory entityFactory;		
	
	public edu.gtcfla.km.repositories.CategoryRepo<Category, String> getCategoryRepo() {
		return categoryRepo;
	}

	public void setCategoryRepo(edu.gtcfla.km.repositories.CategoryRepo<Category, String> categoryRepo) {
		this.categoryRepo = categoryRepo;
	}

	@Override
	public Set<UserGroupPermissionListVO> listUserGroupPermission(
			String categoryId, String query) throws BusinessOperationException {

		
		Map<String,UserGroup> allUserGroupMap = userGroupRepo.findAllMap(query);
		
		Set<String>  userGroupIds = allUserGroupMap.keySet();
		
		// --- find all perm by categoryId and userId ---
		Map<String , UserGroupPermission> userGropupCateMap =  
				userGroupPermissionRepo.findUserGroupPermisionByCateAndUserGroupIds(categoryId, userGroupIds);
		
		
		Set<UserGroupPermissionListVO> ugpl = new LinkedHashSet<UserGroupPermissionListVO>();
		
		// --- show item ---
		for (Map.Entry<String, UserGroup> item :  allUserGroupMap.entrySet() ) {
			String key = item.getKey();
			UserGroup ug = item.getValue();
			
			UserGroupPermission ugPerm = userGropupCateMap.get( key );
			
			UserGroupPermissionListVO ugplv = null;
			if (ugPerm != null) {
				ugplv = new UserGroupPermissionListVO( ugPerm );
			} else {
				ugplv = new UserGroupPermissionListVO();
			}
			ugplv.setUserGroupId( ug.getId() );
			ugplv.setCategoryId( categoryId );
			ugplv.setGroupName( ug.getGroupName() );
			ugpl.add( ugplv );
		}
	
		return ugpl;
	}

	@Override
	public void updateUserGroupPermissions(String categoryId,
			Set<UserGroupPermissionListVO> userPermisList)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		
		// --- find all category under this category id ---
		Map<String , Category>  cateMap = categoryRepo.findAllMap();
		
		//  --- update all permission for every categories ---
		GenTreeModelBuilder<Category> genTreeModel = new GenTreeModelBuilder<Category>(cateMap);
		
		genTreeModel.generate();
		
		Map<String , TreeNode>  treeMap = genTreeModel.getResultMap();
		
		Set<UserGroupPermission> newUpdatePermission = null;
		
		if (categoryId != null && categoryId.equals("root") ) {
			newUpdatePermission = new LinkedHashSet<UserGroupPermission>();

			Set<TreeNode> allTreeNodeBaseRoot = genTreeModel.getResultSet();
			
			for (TreeNode treeNode : allTreeNodeBaseRoot) {
				newUpdatePermission.addAll( updateAllDepthPermission( treeNode ,  userPermisList ) ) ;
			}
			
		} else {
			TreeNode treeNode = treeMap.get(categoryId);
			newUpdatePermission = updateAllDepthPermission( treeNode ,  userPermisList );
			
		}
		
		// --- remove old permission ---
		Set<String> userGroupIds = new LinkedHashSet<String>();
		Set<String> cateIds = new LinkedHashSet<String>();
		
		for (UserGroupPermission up : newUpdatePermission) {
			userGroupIds.add( up.getUserGroupId() );
			cateIds.add( up.getCategoryId() );
		}
		
		userGroupPermissionRepo.removeAllByCateUserGroupIds(cateIds, userGroupIds);
		
		// --- add new permisson ---
		userGroupPermissionRepo.saveAll( newUpdatePermission );

	}

	private Set<UserGroupPermission> updateAllDepthPermission(TreeNode treeNode , Set<UserGroupPermissionListVO> groupPermisList) {
		
		Set<UserGroupPermission> upSet = new LinkedHashSet<UserGroupPermission>();
		
		// --- update tree node ---
		for (UserGroupPermissionListVO udpl : groupPermisList) {
			UserGroupPermission newEntity = entityFactory.create( UserGroupPermission.class );
			BeanUtils.copyProperties( udpl.getEntity() , newEntity);
			newEntity.setCategoryId( treeNode.getId() );
			upSet.add( newEntity );
	
		}

		Collection<TreeNode> children = treeNode.getChildren();
		if (children != null && !children.isEmpty() ) {

			for (TreeNode child : children ) {
				Set<UserGroupPermission> subAllPerms = updateAllDepthPermission(child , groupPermisList);
				upSet.addAll( subAllPerms );
			}
			
		}
		
		return upSet;
		
	}	
	
	
	@Override
	public Set<CurrentUserCategoryPermissionVO> getAllCategoryPermissionFormCurrentUser()
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}
	

	

}
